package cn.gdut.chengcai.controller;

import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import cn.gdut.chengcai.base.ConstantUtil;
import cn.gdut.chengcai.base.EmailUtil;
import cn.gdut.chengcai.base.IdGenerator;
import cn.gdut.chengcai.base.IdentifyCodeUtil;
import cn.gdut.chengcai.base.JsonUtil;
import cn.gdut.chengcai.base.MessageUtil;
import cn.gdut.chengcai.base.RequestUtil;
import cn.gdut.chengcai.base.ResponseData;
import cn.gdut.chengcai.base.SystemConstantUtil;
import cn.gdut.chengcai.entity.CountInfo;
import cn.gdut.chengcai.entity.KeyValueInfo;
import cn.gdut.chengcai.entity.KeyValueInfoExample;
import cn.gdut.chengcai.entity.MemberInfo;
import cn.gdut.chengcai.entity.MemberInfoExample;
import cn.gdut.chengcai.entity.PersonalInfo;
import cn.gdut.chengcai.entity.PersonalInfoExample;
import cn.gdut.chengcai.entity.ValidateLogInfo;
import cn.gdut.chengcai.enums.CaptchaType;
import cn.gdut.chengcai.enums.EmailTemplateType;
import cn.gdut.chengcai.enums.EmailTemplateTypeParam;
import cn.gdut.chengcai.enums.MemberRegisterType;
import cn.gdut.chengcai.service.BlacklistInfoService;
import cn.gdut.chengcai.service.CountInfoService;
import cn.gdut.chengcai.service.CourseInfoService;
import cn.gdut.chengcai.service.EmailLogInfoService;
import cn.gdut.chengcai.service.EmailTemplateInfoService;
import cn.gdut.chengcai.service.KeyValueInfoService;
import cn.gdut.chengcai.service.MemberInfoService;
import cn.gdut.chengcai.service.PersonalInfoService;
import cn.gdut.chengcai.service.ValidateLogInfoService;
import cn.gdut.chengcai.vo.MemberInfoVo;

@Controller
@RequestMapping("/auth")
public class AuthController {

	@Autowired
	protected MemberInfoService memberInfoService;

	@Autowired
	protected PersonalInfoService personalInfoService;

	@Autowired
	protected KeyValueInfoService keyValueInfoService;

	@Autowired
	protected BlacklistInfoService blacklistInfoService;

	@Autowired
	protected CourseInfoService courseInfoService;

	@Autowired
	protected EmailTemplateInfoService emailTemplateInfoService;

	@Autowired
	protected EmailLogInfoService emailLogInfoService;

	@Autowired
	protected ValidateLogInfoService validateLogInfoService;

	@Autowired
	protected CountInfoService countInfoService;

	/**
	 * 注册操作
	 */
	@RequestMapping(value = "/registerAction", method = RequestMethod.POST)
	@ResponseBody
	public ResponseData<Object> registerAction(@RequestBody String jsonString, HttpServletRequest request,
			HttpSession session) {
		ResponseData<Object> result = new ResponseData<>();
		result.setIsSuccess(false);
		MemberInfoVo param = (MemberInfoVo) JsonUtil.fromJson(jsonString, MemberInfoVo.class);

		// 是否开放注册
		KeyValueInfoExample keyvalueExample = new KeyValueInfoExample();
		keyvalueExample.createCriteria().andKeyEqualTo(SystemConstantUtil.DEFAULT_CONFIG_IS_OPEN_REGISTER);
		List<KeyValueInfo> keyvalueList = keyValueInfoService.selectByExample(keyvalueExample);
		if ((null == keyvalueList) || (keyvalueList.size() == 0)) {
			result.setMessage(MessageUtil.DEFAULT_CONFIG_CLOSED_REGISTER);
			return result;
		} else {
			KeyValueInfo info = keyvalueList.get(0);
			if ((info == null) || (info.getValue().equals("0"))) {
				result.setMessage(MessageUtil.DEFAULT_CONFIG_CLOSED_REGISTER);
				return result;
			}
		}

		if (StringUtils.isEmpty(param.getEmail()) || StringUtils.isEmpty(param.getPassword()) == true) {
			result.setMessage(MessageUtil.PARAM_ERROR);
			return result;
		}

		// 查询该邮箱是否已被注册过
		MemberInfoExample example = new MemberInfoExample();
		example.createCriteria().andEmailEqualTo(param.getEmail()).andIsDeletedEqualTo(false);
		List<MemberInfo> list = memberInfoService.selectByExample(example);

		if ((list != null) && (list.size() > 0)) {
			result.setMessage(MessageUtil.EMAIL_IS_EXIST_ERROR);
			return result;
		}

		try {
			String[] args = new String[2];
			args[0] = param.getEmail();
			args[1] = UUID.randomUUID().toString().replace("-", "");// uuid设置密钥
			String ip = RequestUtil.getRemoteHost(request);

			// 发送邮件
			if (EmailUtil.sendSystemMail(emailLogInfoService, emailTemplateInfoService, keyValueInfoService, ip,
					EmailTemplateType.VERIFY.getValue(), param.getEmail(), args) == false) {
				result.setMessage(MessageUtil.EMAIL_SEND_FAILURE);
				return result;
			}

			Date date = new Date(); // 设置密钥过期时间
			Calendar ca = Calendar.getInstance();
			ca.setTime(date);
			ca.add(Calendar.HOUR_OF_DAY, 24);// 默认有效期是24小时
			MemberInfo member = new MemberInfo();
			member.setSn(IdGenerator.generatorMemberSn());
			member.setRegisterType((byte) MemberRegisterType.EMAIL.getValue());// 注册类型
			member.setUsername(param.getEmail());
			member.setUserAvatarUrl(null);
			member.setPassword(param.getPassword());
			member.setEmail(param.getEmail());
			member.setIsMailActivated(false);
			member.setLastestLoginTime(date);
			member.setLastestLoginIp(ip);
			member.setTotalLoginNum(1);
			member.setIsAllowLogin(true);
			member.setIsActivated(false);
			member.setSecretKey(args[1]);
			member.setOutDate(ca.getTime());
			member.setIsDeleted(false);
			member.setCreateTime(date);
			memberInfoService.insert(member);

			PersonalInfo person = new PersonalInfo();
			person.setSn(member.getSn());
			person.setUserAvatarUrl(member.getUserAvatarUrl());
			person.setProvince(null);
			person.setCity(null);
			person.setDistrict(null);
			person.setStreet(null);
			person.setIsDeleted(false);
			person.setSn(member.getSn());
			person.setCreateTime(date);
			personalInfoService.insert(person);

			// 更新统计信息
			CountInfo countInfo = countInfoService.selectByPrimaryKey(1L);
			if (null != countInfo.getTotalRegisteredCount()) {
				countInfo.setTotalRegisteredCount(countInfo.getTotalRegisteredCount() + 1);
			} else {
				countInfo.setTotalRegisteredCount(1L);
			}
			countInfoService.updateByPrimaryKey(countInfo);

			initSession(session, member, person);

			result.setIsSuccess(true);
		} catch (Exception e) {
			e.printStackTrace();
			result.setMessage(MessageUtil.SYSTEM_ERROR);
			// log.error(e.getMessage(), e);
		}

		return result;
	}

	/**
	 * 重新发送邮件操作
	 */
	@RequestMapping(value = "/resendMailAction", method = RequestMethod.POST)
	@ResponseBody
	public ResponseData<Object> resendMailAction(@RequestBody String jsonString, HttpServletRequest request,
			HttpSession session) {
		ResponseData<Object> result = new ResponseData<>();
		result.setIsSuccess(false);

		EmailTemplateTypeParam param = (EmailTemplateTypeParam) JsonUtil.fromJson(jsonString,
				EmailTemplateTypeParam.class);

		MemberInfo entity =	(MemberInfo) session.getAttribute(ConstantUtil.STR_MEMBER); 
		if (entity == null) {
			result.setMessage(MessageUtil.ACCOUNT_NOT_LOGIN_ERROR);
			return result;
		}

		// 判断是否超过最大邮件发送次数
		/*	EmailLogInfoExample example = new EmailLogInfoExample();
			example.createCriteria().andToListEqualTo(entity.getEmail()).andCreateTimeEqualTo(new Date());
			Integer currentAttemptNumber = (int) emailLogInfoService.countByExample(example);
			if (StringUtils.isEmpty(currentAttemptNumber.toString()) == false
					&& currentAttemptNumber >= AuthController.MAX_SEND_EMAIL_NUMBER) {
				result.setMessage(MessageUtil.MAX_SEND_EMAIL_NUMBER);
				return result;
			}*/

		try {
			if (param.getType() == EmailTemplateType.VERIFY.getValue()) {
				String[] args = new String[2];
				args[0] = entity.getUsername();
				args[1] = UUID.randomUUID().toString().replace("-", "");// uuid设置密钥
				String ip = RequestUtil.getRemoteHost(request);

				// 发送邮件
				if (EmailUtil.sendSystemMail(emailLogInfoService, emailTemplateInfoService, keyValueInfoService, ip,
						EmailTemplateType.VERIFY.getValue(), entity.getEmail(), args) == false) {
					result.setMessage(MessageUtil.EMAIL_SEND_FAILURE);
				} else {
					Date date = new Date();
					// 设置密钥过期时间
					Calendar ca = Calendar.getInstance();
					ca.setTime(date);
					ca.add(Calendar.HOUR_OF_DAY, 24);// 默认有效期是24小时
					entity.setOutDate(ca.getTime());
					entity.setSecretKey(args[1]);
					memberInfoService.updateByPrimaryKey(entity);
					result.setIsSuccess(true);
				}
			} else if (param.getType() == EmailTemplateType.CAPTCHA.getValue()) { // 验证码邮件
				String[] args = new String[3];
				args[0] = entity.getUsername();
				args[1] = IdentifyCodeUtil.getEmailIdentifyCode(6);
				// 判断获取验证码的业务操作类型以动态修改邮件信息
				if (param.getCaptchaType().intValue() == CaptchaType.BIND_ALIPAYACCOUNT.getValue()) {
					args[2] = CaptchaType.BIND_ALIPAYACCOUNT.getString();
				} else if (param.getCaptchaType().intValue() == CaptchaType.BIND_BANKACCOUNT.getValue()) {
					args[2] = CaptchaType.BIND_BANKACCOUNT.getString();
				} else if (param.getCaptchaType().intValue() == CaptchaType.MODIFY_ALIPAYACCOUNT.getValue()) {
					args[2] = CaptchaType.MODIFY_ALIPAYACCOUNT.getString();
				} else if (param.getCaptchaType().intValue() == CaptchaType.MODIFY_BANKACCOUNT.getValue()) {
					args[2] = CaptchaType.MODIFY_BANKACCOUNT.getString();
				} else {
					result.setMessage("您的业务不正确！获取验证码失败");
					return result;
				}

				session.setAttribute(ConstantUtil.SESSION_IDENTIFY_CODE, args[1]);

				String ip = RequestUtil.getRemoteHost(request);

				// 发送邮件
				if (EmailUtil.sendSystemMail(emailLogInfoService, emailTemplateInfoService, keyValueInfoService, ip,
						EmailTemplateType.CAPTCHA.getValue(), entity.getEmail(), args) == false) {
					result.setMessage(MessageUtil.EMAIL_SEND_FAILURE);
				} else {
					Date date = new Date(); // 设置密钥过期时间
					Calendar ca = Calendar.getInstance();
					ca.setTime(date);
					ca.add(Calendar.HOUR_OF_DAY, 2);// 默认有效期是2小时
					entity.setOutDate(ca.getTime());
					entity.setSecretKey(args[1]);
					memberInfoService.updateByPrimaryKey(entity);
					result.setIsSuccess(true);
				}
			}

		} catch (Exception e) {
			result.setMessage(MessageUtil.SYSTEM_ERROR);
			// log.error(e.getMessage(), e);
		}
		return result;
	}

	/**
	 * 登录操作
	 */
	@RequestMapping(value = "/loginAction", method = RequestMethod.POST)
	@ResponseBody
	public ResponseData<Object> loginAction(@RequestBody String jsonString, HttpServletRequest request,
			HttpSession session, ModelMap map) {
		ResponseData<Object> result = new ResponseData<>();
		result.setIsSuccess(false);

		// 是否开放登录
		KeyValueInfoExample keyvalueExample = new KeyValueInfoExample();
		keyvalueExample.createCriteria().andKeyEqualTo(SystemConstantUtil.DEFAULT_CONFIG_IS_OPEN_LOGIN);
		List<KeyValueInfo> keyvalueList = keyValueInfoService.selectByExample(keyvalueExample);
		if ((null == keyvalueList) || (keyvalueList.size() == 0)) {
			result.setMessage(MessageUtil.DEFAULT_CONFIG_CLOSED_LOGIN);
			return result;
		} else {
			KeyValueInfo info = keyvalueList.get(0);
			if ((info == null) || (info.getValue().equals("0"))) {
				result.setMessage(MessageUtil.DEFAULT_CONFIG_CLOSED_LOGIN);
				return result;
			}
		}

		MemberInfoVo param = (MemberInfoVo) JsonUtil.fromJson(jsonString, MemberInfoVo.class);
		String ip = RequestUtil.getRemoteHost(request);

		try {
			if (param != null && param.getEmail() != null && param.getPassword() != null) {

				// 查找该登录用户
				MemberInfoExample memberExample = new MemberInfoExample();
				memberExample.createCriteria().andEmailEqualTo(param.getEmail());
				List<MemberInfo> list = memberInfoService.selectByExample(memberExample);
				if ((list == null) || (list.size() == 0)) {
					result.setMessage(MessageUtil.ACCOUNT_NOT_EXIST_ERROR);
					return result;
				}

				memberExample.clear();

				memberExample.createCriteria().andEmailEqualTo(param.getEmail())
						.andPasswordEqualTo(param.getPassword());
				list = memberInfoService.selectByExample(memberExample);
				if ((list == null) || (list.size() == 0)) {
					result.setMessage(MessageUtil.PASSWORD_NOT_MATCH);
					return result;
				} else {

					MemberInfo member = list.get(0);
					// 判断是否允许登录
					if (member.getIsAllowLogin() == false) {
						result.setMessage(MessageUtil.BLACK_LIST_ACCOUNT);
						return result;
					}
					if (null == member.getTotalLoginNum()) {
						member.setTotalLoginNum(1);
					} else {
						member.setTotalLoginNum(member.getTotalLoginNum() + 1);
					}
					Date date = new Date();
					member.setLastestLoginIp(ip);
					member.setLastestLoginTime(date);
					memberInfoService.updateByPrimaryKey(member);

					PersonalInfoExample pExample = new PersonalInfoExample();
					PersonalInfoExample.Criteria pCriteria = pExample.createCriteria();
					pCriteria.andSnEqualTo(member.getSn());
					PersonalInfo person = personalInfoService.selectByExample(pExample).get(0);

					// 更新统计信息
					CountInfo countInfo = countInfoService.selectByPrimaryKey(1L);
					if (null != countInfo.getTotalLoginCount()) {
						countInfo.setTotalLoginCount(countInfo.getTotalLoginCount() + 1);
					} else {
						countInfo.setTotalLoginCount(1L);
					}
					countInfoService.updateByPrimaryKey(countInfo);

					initSession(session, member, person);

					result.setIsSuccess(true);
				}

			}
		} catch (Exception e) {
			e.printStackTrace();
			result.setMessage(MessageUtil.SYSTEM_ERROR);
			// log.error(e.getMessage(), e);
		} finally {
			ValidateLogInfo validateLog = new ValidateLogInfo();
			validateLog.setName(param.getUsername());
			validateLog.setIp(ip);
			validateLog.setDescription(result.getMessage());
			validateLog.setIsAdmin(false);
			validateLog.setIsSuccessed(result.getIsSuccess());
			validateLog.setCreateTime(new Date());
			validateLogInfoService.insert(validateLog);
		}
		return result;
	}

	/**
	 * 注销操作
	 */
	@RequestMapping("/logoutAction")
	public String logoutAction(HttpSession session) {

		// 由于与后端管理系统共用session，因此session不能invalidate
		session.removeAttribute(ConstantUtil.STR_MEMBER);
		session.removeAttribute(ConstantUtil.STR_PERSON);
		session.removeAttribute(ConstantUtil.STR_USER_ACTIVED);
		// session.invalidate();

		return "redirect:/index.html";
	}

	/**
	 * 账户激活
	 */
	@RequestMapping("/activateAccount")
	public String activateAccount(HttpServletRequest request, ModelMap map, HttpSession session) {
		// 密钥已经失效，返回错误！！！
		String secretKey = RequestUtil.getParameter(request, "uuid");
		if (StringUtils.isEmpty(secretKey) == true) {
			map.put("result", MessageUtil.SECRECT_KEY_INVALID);
			return "/personal/auth/activateFailure";
		}

		MemberInfoExample example = new MemberInfoExample();
		example.createCriteria().andSecretKeyEqualTo(secretKey);
		List<MemberInfo> list = memberInfoService.selectByExample(example);
		if (list != null && list.size() > 0) {
			MemberInfo member = list.get(0);
			PersonalInfoExample pExample = new PersonalInfoExample();
			pExample.createCriteria().andSnEqualTo(member.getSn());
			PersonalInfo person = personalInfoService.selectByExample(pExample).get(0);
			if (member.getOutDate().before(new Date()) || member.getIsActivated() == true) {// 激活日期已经过期或者账户已经激活
				map.put("result", MessageUtil.SECRECT_KEY_INVALID);
				return "/personal/auth/activateFailure";
			} else {
				member.setIsMailActivated(true);
				member.setIsActivated(true);
				session.setAttribute(ConstantUtil.STR_USER_ACTIVED, true);
				memberInfoService.updateByPrimaryKey(member);

				if (session != null) {// 重新加载Session
					initSession(session, member, person);
				}

				// 更新统计信息
				CountInfo countInfo = countInfoService.selectByPrimaryKey(1L);
				if (null != countInfo.getTotalActivationCount()) {
					countInfo.setTotalActivationCount(countInfo.getTotalActivationCount() + 1);
				} else {
					countInfo.setTotalActivationCount(1L);
				}
				countInfoService.updateByPrimaryKey(countInfo);

				return "/personal/auth/activateSuccess";
			}
		} else {
			map.put("result", MessageUtil.SECRECT_KEY_INVALID);
			return "/personal/auth/activateFailure";
		}

	}

	/**
	 * 信息重新认证
	 */
	/*@RequestMapping("/info/reAuthAction")
	@ResponseBody
	public ResponseData<Object> reAuthAction(HttpServletRequest request, HttpSession session) {
		ResponseData<Object> result = new ResponseData<>();
		result.setMessage(MessageUtil.SYSTEM_ERROR);
		result.setIsSuccess(false);
		try {
			MemberInfo member = memberInfoService.selectByPrimaryKey(AccountUtil.getUid(session));
			member.setStatus((byte) MemberStatus.WAIT_AUTH.getValue());
			// 保存数据库
			memberInfoService.updateByPrimaryKey(member);
			result.setIsSuccess(true);
		} catch (Exception e) {
			result.setMessage(MessageUtil.SYSTEM_ERROR);
			// log.error(e.getMessage(), e);
		}
		return result;
	}*/

	/**
	 * 获取验证码操作
	 */
	@RequestMapping(value = "/getIdentifyCodeFromSession", method = { RequestMethod.POST })
	@ResponseBody
	public ResponseData<Object> getIdentifyCodeFromSession(HttpSession session) {
		ResponseData<Object> result = new ResponseData<>();
		result.setIsSuccess(false);
		try {
			String code = (String) session.getAttribute(ConstantUtil.SESSION_IDENTIFY_CODE);
			if (code == null) {
				code = "";
			}
			result.setData(code);
			result.setIsSuccess(true);
		} catch (Exception e) {
			result.setMessage(MessageUtil.SYSTEM_ERROR);
			// log.error(e.getMessage(), e);
		}
		return result;
	}

	private static void initSession(HttpSession session, MemberInfo member, PersonalInfo person) {
		if (null != member) {
			session.setAttribute(ConstantUtil.STR_MEMBER, member);
		}
		if (null != person) {
			session.setAttribute(ConstantUtil.STR_PERSON, person);
		}
		if (null != member.getIsActivated()) {
			session.setAttribute(ConstantUtil.STR_USER_ACTIVED, member.getIsActivated().toString());
		}
	}
}
